package cn.neusoft.controller;

import cn.neusoft.domain.CargoDescription;
import cn.neusoft.domain.CargoVariety;
import cn.neusoft.service.CargoAndDescriptionService;
import cn.neusoft.tool.PageSet;
import cn.neusoft.vo.ResultBean;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.text.SimpleDateFormat;
import java.util.*;

@RestController
@RequestMapping("/cargo")
public class CargoAndDescriptionController {
    @Autowired
    private CargoAndDescriptionService cargoAndDescriptionService;
    private static final String UNSETTING_NAME = "未设置";
    @PostMapping("/carDesRegister")
    @ApiOperation(value = "添加新商品描述")
    public synchronized ResultBean cargoDesRegister(@RequestBody Map<String, String> map){
        ResultBean result = null;


        if(map != null) {
          try {
            String name = map.get("name");
            String variety = map.get("variety");
            String unit = map.get("unit");
            String costPrice = map.get("costPrice");
            String discount = map.get("discount");
            String price = map.get("salePrice");
            String type = map.get("type");
            String manufacture = map.get("manufacture");
            String provider = map.get("provider");
            String notes = map.get("notes");
            java.sql.Date from = new java.sql.Date(new SimpleDateFormat("yyyy-MM-dd").parse(map.get("dateFrom")).getTime());
            java.sql.Date to = new java.sql.Date(new SimpleDateFormat("yyyy-MM-dd").parse(map.get("dateTo")).getTime());
            boolean isChange = Boolean.parseBoolean(map.get("change"));
            boolean isWithdraw = Boolean.parseBoolean(map.get("withdraw"));

            CargoDescription cargoDescription = new CargoDescription(name, unit, Double.parseDouble(price), Double.parseDouble(costPrice), type, manufacture, provider, from,
              to, isWithdraw, isChange, notes, discount);
            int carReply = cargoAndDescriptionService.cargoDesRegister(cargoDescription);
            if(carReply == 0){
                return ResultBean.error(1, "错误");
            }
            int varReply = 1;
            if(variety != null && !variety.equals("")){
                CargoVariety tempVar = cargoAndDescriptionService.getVarietyByName(variety);
                if(tempVar == null){
                    varReply = -1;
                }
                else{

                    if(!tempVar.getChildrenList().contains(name)){
                        tempVar.getCargoNameList().add(name);
                        varReply = cargoAndDescriptionService.updateVariety(tempVar);
                    }
                }
            }
            else{
                CargoVariety tempVar = cargoAndDescriptionService.getVarietyByName(UNSETTING_NAME);
                if(tempVar == null){
                    varReply = -1;
                }
                else{
                    if(!tempVar.getChildrenList().contains(name)){
                        tempVar.getCargoNameList().add(name);
                        varReply = cargoAndDescriptionService.updateVariety(tempVar);
                    }
                }
            }
            if(carReply > 0){
                result = ResultBean.success();
            }
            else{
                result = ResultBean.error(1, "异常");
            }
          } catch (Exception e) {
            e.printStackTrace();
            result = ResultBean.error(1, "异常");
          }

        }

        return result;
    }
    @ApiOperation(value = "某一商品种类注册")
    @PostMapping("/varRegister")
    public synchronized ResultBean varietyRegister(@RequestBody Map<String, Object> map){
        ResultBean result = null;


        if(map != null){
            try{
              String name = (String) map.get("name");
              int parentID = Integer.parseInt((String) map.get("parentID"));
              List<Map<String, String>> cargoInf = (List<Map<String, String>>) map.get("cargoInf");
              List<String> list = new ArrayList<>();
              CargoVariety cargoVariety = new CargoVariety(name, parentID);
              for(Map<String, String> m : cargoInf){
                list.add(m.get("cargoName"));
              }
              cargoVariety.setCargoNameList(list);
              int reply = cargoAndDescriptionService.varietyRegister(cargoVariety);
              switch(reply){
                case 1:
                  result = ResultBean.success();
                  break;
                case 0:
                  result = ResultBean.error(3011, "商品种类添加失败");
                  break;
                default:
                  result = ResultBean.error(3012, "添加商品种类未知错误");
                  break;
              }
            }catch (Exception e){
              e.printStackTrace();
              result = ResultBean.error(3010, "商品种类数据为空");
            }
        }
        else{
            result = ResultBean.error(3010, "商品种类数据为空");
        }

        return result;
    }
    @ApiOperation(value = "商品种类删除")
    @GetMapping("/varDelete/{varName}")
    public synchronized ResultBean varietyDelete(@PathVariable("varName") String varName){
        ResultBean result = null;

        if(varName != null){
            if(varName.equals(UNSETTING_NAME)){
                return ResultBean.error(1, "无权限");
            }
            CargoVariety cargoVariety = cargoAndDescriptionService.getVarietyByName(varName);
            if(cargoVariety != null){
                for(CargoVariety c : cargoVariety.getChildrenList()){
                    c.setParentID(0);
                    if(cargoAndDescriptionService.updateVariety(c) != 1){
                        break;
                    }
                }
                int reply = cargoAndDescriptionService.varietyDelete(varName);
                switch(reply){
                    case 1:
                        result = ResultBean.success();
                        break;
                    case 0:
                        result = ResultBean.error(3021, "商品种类删除失败");
                        break;
                    default:
                        result = ResultBean.error(3022, "删除商品种类未知错误");
                        break;
                }
            }

        }
        else{
            result = ResultBean.error(3020, "错误");
        }

        return result;
    }
    @ApiOperation(value = "获取某层的所有商品种类")
    @GetMapping("/getVarietyByLayers/{layer}")
    public ResultBean getVarietyByLayers(@PathVariable("layer") int layer){
        ResultBean resultBean = null;

        List<CargoVariety> list = cargoAndDescriptionService.getVarietyByLayers(layer);

        resultBean = ResultBean.success(list);

        return resultBean;
    }
    @PostMapping("/getVarietyByLayers")
    public ResultBean getVarietyByLayersAndParent(@RequestBody Map<String, String> map){
        ResultBean resultBean = null;
        if(map.containsKey("layer") && map.containsKey("varName")){
            List<CargoVariety> list = new ArrayList<CargoVariety>();
            for(CargoVariety cv : cargoAndDescriptionService.getVarietyByLayers(Integer.parseInt(map.get("layer")))){
                if(cv.getVarietyName().equals(map.get("varName"))){
                    list.add(cv);
                }
            }
            resultBean = ResultBean.success(list);
        }
        else{
            resultBean = ResultBean.error(1, "输入错误");
        }


        return resultBean;
    }
    @ApiOperation(value = "获取某一类的所有商品描述")
    @GetMapping("/getCargoByVarName/{varName}")
    public ResultBean getCargoDesByVarName(@PathVariable("varName") String varName){
        ResultBean resultBean = null;

        List<CargoDescription> list = cargoAndDescriptionService.getCargoDesByVarName(varName);
        resultBean = ResultBean.success(list);

        return resultBean;
    }
    @ApiOperation(value = "删除某一商品描述")
    @GetMapping("/cargoDesDelete/{carName}")
    public synchronized ResultBean cargoDesDelete(@PathVariable("carName") String carName){
        ResultBean resultBean = null;

        if(carName != null){
            int reply = cargoAndDescriptionService.cargoDesDelete(carName);
            switch(reply){
                case 1:
                    resultBean = ResultBean.success();
                    break;
                case 0:
                    resultBean = ResultBean.error(3051, "商品描述删除失败");
                    break;
                default:
                    resultBean = ResultBean.error(3052, "删除商品描述未知错误");
                    break;
            }
        }
        else{
            resultBean = ResultBean.error(3050, "商品描述名称为空");
        }

        return resultBean;
    }
    @ApiOperation(value = "删除一系列商品描述")
    @PostMapping("/cargoDesDeleteSeries")
    public synchronized ResultBean cargoDesDeleteAll(@PathVariable("carName") List<String> carNames){
        ResultBean resultBean = null;

        if(carNames != null){
            int reply = 0;
            for(String s : carNames){
                reply = cargoAndDescriptionService.cargoDesDelete(s);
                if(reply != 1){
                    break;
                }
            }
            switch(reply){
                case 1:
                    resultBean = ResultBean.success();
                    break;
                case 0:
                    resultBean = ResultBean.error(3051, "商品描述删除失败");
                    break;
                default:
                    resultBean = ResultBean.error(3052, "删除商品描述未知错误");
                    break;
            }
        }
        else{
            resultBean = ResultBean.error(3050, "商品描述名称为空");
        }

        return resultBean;
    }
    @PostMapping("/carToVar")
    @ApiOperation(value = "添加商品描述的种类信息")
    public synchronized ResultBean cargosToVariety(@RequestBody Map<String, String> request){
        ResultBean resultBean = null;

        if(request != null){
            String varName, desName;
            varName = request.get("varName");
            desName = request.get("desName");
            if(varName != null && desName != null){
                int reply = cargoAndDescriptionService.cargosToVariety(desName, varName);
                switch(reply){
                    case 1:
                        resultBean = ResultBean.success();
                        break;
                    case 0:
                        resultBean = ResultBean.error(3061, "添加商品描述的种类信息失败");
                        break;
                    default:
                        resultBean = ResultBean.error(3062, "添加商品描述的种类信息未知错误");
                        break;
                }
            }
            else{
                resultBean = ResultBean.error(3063, "缺少输入数据");
            }

        }
        else{
            resultBean = ResultBean.error(3060, "输入数据为空");
        }

        return resultBean;
    }
    @PostMapping("/getCarDesPage")
    public ResultBean getCarDesPage(@RequestBody Map<String, String> map){
        ResultBean resultBean = null;

        if(map != null){
            String pageNum = map.get("pageNum");
            String pageSize = map.get("pageSize");
            String sort = map.get("variety");
            String cargoName = map.get("name");



            List<CargoDesReturn> l = new ArrayList<>();

            Queue<CargoVariety> cargoVarieties = new LinkedList<>();

            if(!sort.equals("")){
                List<CargoDescription> tempDesList = cargoAndDescriptionService.getCargoDesByVarName(sort);
                for(CargoDescription cargoDescription : tempDesList){
                    if(!cargoName.equals("") && !cargoDescription.getName().equals(cargoName)){
                        continue;
                    }
                    CargoDesReturn cargoDesReturn = new CargoDesReturn(sort, cargoDescription.getId(),
                            cargoDescription.getName(), cargoDescription.getUnit(), Double.toString(cargoDescription.getSalePrice()), Double.toString(cargoDescription.getCostPrice()),
                            cargoDescription.getType(), cargoDescription.getManufacture(), cargoDescription.getProvider(), cargoDescription.getDateFrom(),
                            cargoDescription.getDateTo(), Boolean.toString(cargoDescription.isWithdraw()), Boolean.toString(cargoDescription.isChange()), cargoDescription.getNotes(), cargoDescription.getDiscount());

                    l.add(cargoDesReturn);
                }
            }
            else{
                List<CargoVariety> roots = cargoAndDescriptionService.getVarietyRoot();
                for(CargoVariety c : roots){
                    cargoVarieties.offer(c);
                }
                while(!cargoVarieties.isEmpty()){
                    CargoVariety cargoVariety = cargoVarieties.poll();
                    List<CargoDescription> tempDesList = cargoAndDescriptionService.getCargoDesByVarName(cargoVariety.getVarietyName());
                    for(CargoDescription cargoDescription : tempDesList){
                        if(!cargoName.equals("") && !cargoDescription.getName().equals(cargoName)){
                            continue;
                        }
                        CargoDesReturn cargoDesReturn = new CargoDesReturn(cargoVariety.getVarietyName(), cargoDescription.getId(),
                                cargoDescription.getName(), cargoDescription.getUnit(), Double.toString(cargoDescription.getSalePrice()), Double.toString(cargoDescription.getCostPrice()),
                                cargoDescription.getType(), cargoDescription.getManufacture(), cargoDescription.getProvider(), cargoDescription.getDateFrom(),
                                cargoDescription.getDateTo(), Boolean.toString(cargoDescription.isWithdraw()), Boolean.toString(cargoDescription.isChange()), cargoDescription.getNotes(), cargoDescription.getDiscount());

                        l.add(cargoDesReturn);
                    }

                    for(CargoVariety tempC : cargoVariety.getChildrenList()){
                        cargoVarieties.offer(tempC);
                    }
                }

            }

            if(!pageSize.equals("")){
                try{
                  PageSet<CargoDesReturn> pageSet;
                  int size = Integer.parseInt(pageSize);
                  int num = Integer.parseInt(pageNum);
                  pageSet = new PageSet<CargoDesReturn>(l, size);

                  Map<String, Object> answer = new HashMap<>();
                  answer.put("list", pageSet.getPage(num));
                  answer.put("total", pageSet.getTotal());
                  resultBean = ResultBean.success(answer);

                }catch(Exception e){
                    e.printStackTrace();
                    resultBean = ResultBean.error(3072, "输入数据有误");
                }


            }
            else{
                resultBean = ResultBean.error(3071, "输入数据为空");
            }


        }
        else{
            resultBean = ResultBean.error(3070, "输入数据为空");
        }

        return resultBean;
    }
    @PostMapping("/getVarietyPage")
    public ResultBean getVarietyPage(@RequestBody Map<String, String> map){
      ResultBean resultBean = null;

      List<VarietyReturn> list = new ArrayList<>();

      if(map != null){
        try{
          int layer = 0;
          if(!map.get("layer").equals("")){
            layer = Integer.parseInt(map.get("layer"));
          }
          String name = map.get("name");
          String pageNum = map.get("pageNum");
          String pageSize = map.get("pageSize");
          CargoVariety cargoVariety;
          Queue<CargoVariety> queue = new LinkedList<>();
          if(!name.equals("")) {
            cargoVariety = cargoAndDescriptionService.getVarietyByName(name);
            if(cargoVariety != null){
                queue.offer(cargoVariety);
            }
          }
          else{
            List<CargoVariety> roots = cargoAndDescriptionService.getVarietyRoot();
            for(CargoVariety c : roots){
                queue.offer(c);
            }
          }
          int totalLayer = 1;
          while(!queue.isEmpty()){
              if(layer <= 0){
                  break;
              }
              int size = queue.size();
              for(int i = 1; i <= size; i++){
                  CargoVariety temp = queue.poll();
                  for(CargoVariety c : temp.getChildrenList()){
                      queue.offer(c);
                  }
              }
              layer--;
              totalLayer++;
          }

          while(!queue.isEmpty()){
              CargoVariety temp = queue.poll();
              List<Map<String, String>> l = new ArrayList<>();
              for(String s : temp.getCargoNameList()){
                  Map<String, String> m = new HashMap<String, String>();
                  m.put("cargoName", s);
                  l.add(m);
              }
              VarietyReturn varietyReturn = new VarietyReturn(temp.getId(), temp.getVarietyName(), temp.getParentID(),
                      totalLayer, l);
              list.add(varietyReturn);
          }

          PageSet<VarietyReturn> pageSet = new PageSet<>(list, Integer.parseInt(pageSize));
          Map<String, Object> answer = new HashMap<>();
          answer.put("list", pageSet.getPage(Integer.parseInt(pageNum)));
          answer.put("total", pageSet.getTotal());

          resultBean = ResultBean.success(answer);

        }catch (Exception e){
          e.printStackTrace();
          resultBean = ResultBean.error(1, "异常");
        }
      }
      else{
        resultBean = ResultBean.error(2, "错误");
      }

      return resultBean;
    }
    @PostMapping("/updateCargoDes")
    public synchronized ResultBean updateCargoDes(@RequestBody Map<String, String> map){
      ResultBean result = null;


      if(map != null) {
        try {

          int id = Integer.parseInt(map.get("id"));
            CargoDescription find = cargoAndDescriptionService.getDesByID(id);
            if(find != null){
                String name = map.get("name");
                String variety = map.get("variety");
                String unit = map.get("unit");
                String costPrice = map.get("costPrice");
                String discount = map.get("discount");
                String salePrice = map.get("salePrice");
                String type = map.get("type");
                String manufacture = map.get("manufacture");
                String provider = map.get("provider");
                String notes = map.get("notes");
                java.sql.Date from = new java.sql.Date(new SimpleDateFormat("yyyy-MM-dd").parse(map.get("dateFrom")).getTime());
                java.sql.Date to = new java.sql.Date(new SimpleDateFormat("yyyy-MM-dd").parse(map.get("dateTo")).getTime());
                boolean isChange = Boolean.parseBoolean(map.get("isChange"));
                boolean isWithdraw = Boolean.parseBoolean(map.get("isWithdraw"));

                CargoVariety cargoVariety = cargoAndDescriptionService.findVarHadDesName(find.getName());
                System.out.println((cargoVariety == null) + "!?");

                int varReply = 0;
                int carReply = 0;
                if(cargoVariety == null){
                    return ResultBean.error(1, "错误");
                }
                if(!cargoVariety.getVarietyName().equals(variety)){
                    cargoVariety.getCargoNameList().remove(find.getName());
                    varReply = cargoAndDescriptionService.updateVariety(cargoVariety);
                    CargoVariety newC = cargoAndDescriptionService.getVarietyByName(variety);
                    if(newC != null && varReply > 0){
                        if(!newC.getChildrenList().contains(name)){
                            newC.getCargoNameList().add(name);
                            varReply = cargoAndDescriptionService.updateVariety(newC);
                        }
                    }
                }
                else{
                    if(!name.equals(find.getName())){
                        cargoVariety.getCargoNameList().remove(find.getName());
                        cargoVariety.getCargoNameList().add(name);
                        varReply = cargoAndDescriptionService.updateVariety(cargoVariety);
                    }
                }
                if(varReply > 0){
                    find.setName(name);
                    find.setUnit(unit);
                    find.setCostPrice(Double.parseDouble(costPrice));
                    find.setDiscount(discount);
                    find.setSalePrice(Double.parseDouble(salePrice));
                    find.setType(type);
                    find.setManufacture(manufacture);
                    find.setProvider(provider);
                    find.setNotes(notes);
                    find.setDateFrom(from);
                    find.setDateTo(to);
                    find.setChange(isChange);
                    find.setWithdraw(isWithdraw);

                    carReply = cargoAndDescriptionService.updateCargoDes(find);
                }


                if(carReply > 0){
                    if(varReply > 0){
                        result = ResultBean.success();
                    }
                    else{
                        result = ResultBean.error(1, "错误");
                    }

                }
                else{
                    result = ResultBean.error(1, "错误");

                }


            }

        } catch (Exception e) {
          e.printStackTrace();
          result = ResultBean.error(1, "异常");
        }

      }

      return result;
    }
    @PostMapping("/updateVariety")
    public synchronized ResultBean updateVariety(@RequestBody  Map<String, Object> map){
      ResultBean result = null;


      if(map != null){
        try{
           int id = (int) map.get("id");
           String name = (String) map.get("name");
            CargoVariety cargoVariety = cargoAndDescriptionService.getVarietyByID(id);

            if(cargoVariety != null){
                int parentID = (int) map.get("parentID");
                List<Map<String, String>> cargoInf = (List<Map<String, String>>) map.get("cargoInf");

                cargoVariety.setVarietyName(name);
                cargoVariety.setParentID(parentID);
                List<String> list = new ArrayList<>();
                for(Map<String, String> m : cargoInf){
                    list.add(m.get("cargoName"));
                }
                cargoVariety.setCargoNameList(list);
                int reply = cargoAndDescriptionService.updateVariety(cargoVariety);
                switch(reply){
                    case 1:
                        result = ResultBean.success();
                        break;
                    case 0:
                        result = ResultBean.error(3011, "商品种类添加失败");
                        break;
                    default:
                        result = ResultBean.error(3012, "添加商品种类未知错误");
                        break;
                }
            }
            else{
                result = ResultBean.error(3012, "添加商品种类未知错误");
            }

        }catch (Exception e){
          e.printStackTrace();
          result = ResultBean.error(3010, "商品种类数据为空");
        }
      }
      else{
        result = ResultBean.error(3010, "商品种类数据为空");
      }

      return result;
    }

  private class VarietyReturn {
    private int id;
    private String name;
    private int parentID;
    private int TotalLayers;
    private List<Map<String, String>> cargoDesList;



    public VarietyReturn(int id, String name, int parentID, int totalLayers, List<Map<String, String>> cargoDesList) {
      this.id = id;
      this.name = name;
      this.parentID = parentID;
      TotalLayers = totalLayers;
      this.cargoDesList = cargoDesList;
    }

    public int getId() {
      return id;
    }

    public void setId(int id) {
      this.id = id;
    }

    public String getName() {
      return name;
    }

    public void setName(String name) {
      this.name = name;
    }

    public int getParentID() {
      return parentID;
    }

    public void setParentID(int parentID) {
      this.parentID = parentID;
    }

    public int getTotalLayers() {
      return TotalLayers;
    }

    public void setTotalLayers(int totalLayers) {
      TotalLayers = totalLayers;
    }

    public List<Map<String, String>> getCargoDesList() {
      return cargoDesList;
    }

    public void setCargoDesList(List<Map<String, String>> cargoDesList) {
      this.cargoDesList = cargoDesList;
    }
  }

  private class CargoDesReturn{
        private String variety;
        private int id;
      private String name;
      private String unit;
      private String salePrice;
      private String costPrice;
      private String type;
      private String manufacture;
      private String provider;
      private java.sql.Date dateFrom;
      private java.sql.Date dateTo;
      private String withdraw;
      private String change;
      private String notes;
      private String discount;

      public String getWithdraw() {
          return withdraw;
      }

      public void setWithdraw(String withdraw) {
          this.withdraw = withdraw;
      }

      public String getChange() {
          return change;
      }

      public void setChange(String change) {
          this.change = change;
      }

      public CargoDesReturn(String variety, int id, String name, String unit, String salePrice, String costPrice, String type, String manufacture, String provider, java.sql.Date dateFrom, java.sql.Date dateTo, String Withdraw, String change, String notes, String discount) {
          this.variety = variety;
          this.id = id;
          this.name = name;
          this.unit = unit;
          this.salePrice = salePrice;
          this.costPrice = costPrice;
          this.type = type;
          this.manufacture = manufacture;
          this.provider = provider;
          this.dateFrom = dateFrom;
          this.dateTo = dateTo;
          this.withdraw = Withdraw;
          this.change = change;
          this.notes = notes;
          this.discount = discount;
      }

      public String getVariety() {
          return variety;
      }

      public void setVariety(String variety) {
          this.variety = variety;
      }

      public int getId() {
          return id;
      }

      public void setId(int id) {
          this.id = id;
      }

      public String getName() {
          return name;
      }

      public void setName(String name) {
          this.name = name;
      }

      public String getUnit() {
          return unit;
      }

      public void setUnit(String unit) {
          this.unit = unit;
      }

      public String getSalePrice() {
          return salePrice;
      }

      public void setSalePrice(String salePrice) {
          this.salePrice = salePrice;
      }

      public String getCostPrice() {
          return costPrice;
      }

      public void setCostPrice(String costPrice) {
          this.costPrice = costPrice;
      }

      public String getType() {
          return type;
      }

      public void setType(String type) {
          this.type = type;
      }

      public String getManufacture() {
          return manufacture;
      }

      public void setManufacture(String manufacture) {
          this.manufacture = manufacture;
      }

      public String getProvider() {
          return provider;
      }

      public void setProvider(String provider) {
          this.provider = provider;
      }

      public java.sql.Date getDateFrom() {
          return dateFrom;
      }

      public void setDateFrom(java.sql.Date dateFrom) {
          this.dateFrom = dateFrom;
      }

      public java.sql.Date getDateTo() {
          return dateTo;
      }

      public void setDateTo(java.sql.Date dateTo) {
          this.dateTo = dateTo;
      }

      public String isWithdraw() {
          return withdraw;
      }



      public String isChange() {
          return change;
      }


      public String getNotes() {
          return notes;
      }

      public void setNotes(String notes) {
          this.notes = notes;
      }

      public String getDiscount() {
          return discount;
      }

      public void setDiscount(String discount) {
          this.discount = discount;
      }
  }


}
